/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pro.unal.edu.datasource;

import java.awt.Color;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Carlos Eduardo Bernal Cárdenas
 * @version 1.0
 * @created 20-ago-2011
 */
public class BMPImage extends MyImage {

    /**
     * Info Header 14 data
     */
//    //2 data
//    private String signature;
//    //4 data
//    private int fileSize;
    //4 data
    private int reserved;
    //4 data
//    private int offset;
    /**
     * Header 40 data
     */
    //4 data
    private int sizeInfoHeader = 40;
//    //4 data
//    private int width;
//    //4 data
//    private int height;
    //2 data
    private int planes;
    //2 data
    /**
     * 1 = monocormatic
     * 4 = 4bit palletized
     * 8 = 8bit palletized
     * 16 = 16bit RGB
     * 24 = 24 bit RGB
     */
    private int bitPerPixel;
    //4 data
    private int compression;
    //4 data
    private int imageSize;
    //4 data
    private int xPixelsPerM;
    //4 data
    private int yPixelsPerM;
    //4 data
    private int colorsUsed;
    //4 data
    private int colorsImportant;
    private boolean exist = true;
//    private Color[][] dataImageColor;
    private int rowSize;

    public BMPImage() {
    }

    public BMPImage(String pathImage) {
        setPathImage(pathImage);
        loadImageProperties();
//        for (int i = dataImage.size() - 1; i >= 0; i--) {
//            for (int j = 0; j < dataImage.get(i).size(); j++) {
//                System.out.print(dataImage.get(i).get(j) + " - ");
//            }
//            System.out.println("");
//            System.out.println("i: " + i);
//        }
    }

    @Override
    protected void loadImageProperties() {
        try {
            /**** Load Image Properties****/
            BufferedInputStream is = new BufferedInputStream(new FileInputStream(getPathImage()));
            byte[] header = new byte[54];
            is.read(header, 0, 54);
            //2 data
            setSizeInfoHeader(sizeInfoHeader);
            setSignature(((char) (readBytes(1, header, 0))) + "" + ((char) (readBytes(1, header, 1))));
            //4 data
            setFileSize(readBytes(4, header, 2));
            System.out.println("filesize: " + getFileSize());
            //4 data
            reserved = readBytes(4, header, 6);
            //4 data
            setOffset(readBytes(4, header, 10));
            /**
             * InfoHeader 40 data
             */
            //4 data
            sizeInfoHeader = 40;
            //4 data
            setWidth(readBytes(4, header, 18));
            //System.out.println("Width: " + width);
            //4 data
            setHeight(readBytes(4, header, 22));
            //System.out.println("Height: " + height);
            setDataImageColor(new Color[getWidth()][getHeight()]);
//            dataImageColor = new Color[width + 1][height + 1];
            //2 data
            planes = readBytes(2, header, 26);
            //2 data
            /**
             * 1 = monocormatic
             * 4 = 4bit palletized
             * 8 = 8bit palletized
             * 16 = 16bit RGB
             * 24 = 24 bit RGB
             */
            bitPerPixel = readBytes(2, header, 28);
            //4 data
            compression = readBytes(4, header, 30);
            //4 data
            /**
             * compressed
             */
            imageSize = readBytes(4, header, 34);
            //4 data
            xPixelsPerM = readBytes(4, header, 38);
            //4 data
            yPixelsPerM = readBytes(4, header, 42);
            //4 data
            colorsUsed = readBytes(4, header, 46);
            //4 data
            colorsImportant = readBytes(4, header, 50);

            /**** Load Image****/
            is = new BufferedInputStream(new FileInputStream(getPathImage()));
            System.out.println("BitPerPixel: " + bitPerPixel);
            if (xPixelsPerM != 0) {
                rowSize = bitPerPixel * getWidth() / 32 * 4;
                System.out.println("RowSize: " + ((rowSize * getHeight()) + 54));

            }
            byte[] data = new byte[getFileSize()];
            is.read(data, 0, getFileSize());

            int x = 1;
            int y = 0;
            int i = 54;
            int grow = 3;
            int filter = 0;
            if (bitPerPixel == 32) {
                grow = 4;
            }
            if (bitPerPixel == 24) {
                grow = 3;
            }
            for (; i < data.length - grow && y < getHeight(); i += grow) {
                int a = 127;
                int b = (data[i] + 256 + filter) % 256;
                int g = (data[i + 1] + 256 + filter) % 256;
                int r = (data[i + 2] + 256 + filter) % 256;
                if (bitPerPixel == 32) {
                    a = (data[i + 3] + 128 + filter) % 128;
                }
                Color c = new Color(r, g, b);
                getDataImageColor()[(x - 1) % getWidth()][y] = c;
                if ((x % getWidth()) == 0) {
                    if (getWidth() % 4 != 0) {
                        i += (4 - (3 * getWidth() % 4));
                    }
                    y++;
                }
                x++;
            }
            System.out.println("termino");
            is.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(BMPImage.class.getName()).log(Level.SEVERE, null, ex);
            ex.printStackTrace();
            exist = false;
        } catch (IOException ex) {
            Logger.getLogger(BMPImage.class.getName()).log(Level.SEVERE, null, ex);
            ex.printStackTrace();
        }
    }

    public int getBitPerPixel() {
        return bitPerPixel;
    }

    public void setBitPerPixel(int bitCount) {
        this.bitPerPixel = bitCount;
    }

    public int getColorsImportant() {
        return colorsImportant;
    }

    public void setColorsImportant(int colorsImportant) {
        this.colorsImportant = colorsImportant;
    }

    public int getColorsUsed() {
        return colorsUsed;
    }

    public void setColorsUsed(int colorsUsed) {
        this.colorsUsed = colorsUsed;
    }

    public int getCompression() {
        return compression;
    }

    public void setCompression(int compression) {
        this.compression = compression;
    }

    public boolean isExist() {
        return exist;
    }

    public void setExist(boolean exist) {
        this.exist = exist;
    }

    public int getImageSize() {
        return imageSize;
    }

    public void setImageSize(int imageSize) {
        this.imageSize = imageSize;
    }

    public int getPlanes() {
        return planes;
    }

    public void setPlanes(int planes) {
        this.planes = planes;
    }

    public int getReserved() {
        return reserved;
    }

    public void setReserved(int reserved) {
        this.reserved = reserved;
    }

    public int getSizeInfoHeader() {
        return sizeInfoHeader;
    }

    public void setSizeInfoHeader(int sizeInfoHeader) {
        this.sizeInfoHeader = sizeInfoHeader;
    }

    public int getxPixelsPerM() {
        return xPixelsPerM;
    }

    public void setxPixelsPerM(int xPixelsPerM) {
        this.xPixelsPerM = xPixelsPerM;
    }

    public int getyPixelsPerM() {
        return yPixelsPerM;
    }

    public void setyPixelsPerM(int yPixelsPerM) {
        this.yPixelsPerM = yPixelsPerM;
    }

    private void loadImage() {
        if (exist) {
        }
    }
}
